<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue3 响应式学习游戏 🎮</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
      line-height: 1.6;
      color: #333;
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      min-height: 100vh;
      padding: 20px;
      transition: background 0.5s ease;
    }
    
    .game-container {
      max-width: 1000px;
      margin: 0 auto;
      background: white;
      border-radius: 20px;
      padding: 30px;
      box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
    }
    
    .game-header {
      text-align: center;
      margin-bottom: 30px;
      padding-bottom: 20px;
      border-bottom: 2px solid #667eea;
    }
    
    .game-header h1 {
      color: #667eea;
      font-size: 2.5rem;
      margin-bottom: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .game-header h1 span {
      margin-right: 15px;
    }
    
    .level-selector {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
      gap: 10px;
      margin-bottom: 30px;
    }
    
    .level-btn {
      background: #f0f0f0;
      border: 2px solid #ddd;
      padding: 15px 10px;
      border-radius: 10px;
      cursor: pointer;
      transition: all 0.3s ease;
      font-weight: bold;
      position: relative;
    }
    
    .level-btn.active {
      background: #667eea;
      color: white;
      border-color: #667eea;
      transform: scale(1.05);
    }
    
    .level-btn.completed {
      background: #51cf66;
      color: white;
      border-color: #51cf66;
    }
    
    .level-btn.locked {
      opacity: 0.5;
      cursor: not-allowed;
    }
    
    .level-btn .star {
      position: absolute;
      top: -5px;
      right: -5px;
      color: #ffd43b;
      font-size: 1.2rem;
    }
    
    .game-content {
      background: #f8f9fa;
      border-radius: 15px;
      padding: 25px;
      min-height: 400px;
    }
    
    .level-title {
      color: #667eea;
      font-size: 1.8rem;
      margin-bottom: 20px;
      display: flex;
      align-items: center;
    }
    
    .level-title .emoji {
      margin-right: 10px;
    }
    
    .learning-points {
      background: white;
      border-radius: 10px;
      padding: 20px;
      margin-bottom: 20px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
    }
    
    .learning-points h3 {
      color: #764ba2;
      margin-bottom: 10px;
      font-size: 1.2rem;
    }
    
    .learning-points ul {
      list-style: none;
      padding-left: 20px;
    }
    
    .learning-points li {
      margin-bottom: 8px;
      position: relative;
    }
    
    .learning-points li:before {
      content: "✨";
      position: absolute;
      left: -20px;
      top: 0;
    }
    
    .analogy {
      background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);
      border-radius: 10px;
      padding: 20px;
      margin-bottom: 20px;
      font-style: italic;
      position: relative;
      overflow: hidden;
    }
    
    .analogy h3 {
      color: #d63384;
      margin-bottom: 10px;
      font-style: normal;
    }
    
    .analogy .decoration {
      position: absolute;
      bottom: -10px;
      right: -10px;
      font-size: 5rem;
      opacity: 0.1;
      transform: rotate(20deg);
    }
    
    .demo-area {
      background: white;
      border-radius: 10px;
      padding: 20px;
      margin-bottom: 20px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
    }
    
    .demo-area h3 {
      color: #2563eb;
      margin-bottom: 15px;
    }
    
    /* 关卡1特定样式 */
    .hero-game {
      text-align: center;
      padding: 20px;
    }
    
    .hero-hp {
      font-size: 1.5rem;
      margin-bottom: 20px;
      font-weight: bold;
      color: #dc2626;
    }
    
    .hero-btn {
      background: #ef4444;
      color: white;
      border: none;
      padding: 12px 30px;
      border-radius: 8px;
      font-size: 16px;
      cursor: pointer;
      transition: all 0.3s ease;
    }
    
    .hero-btn:hover:not(:disabled) {
      background: #dc2626;
      transform: scale(1.05);
    }
    
    .hero-btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
      transform: none;
    }
    
    /* 关卡2特定样式 */
    .hero-card {
      background: linear-gradient(135deg, #e0f2fe 0%, #bae6fd 100%);
      border-radius: 15px;
      padding: 25px;
      text-align: center;
    }
    
    .hero-card h3 {
      color: #0369a1;
      margin-bottom: 10px;
      font-size: 1.5rem;
    }
    
    .hero-level {
      font-size: 2rem;
      font-weight: bold;
      color: #0ea5e9;
      margin-bottom: 15px;
    }
    
    .hero-skills {
      margin-bottom: 20px;
      font-size: 1.1rem;
    }
    
    .level-up-btn {
      background: #8b5cf6;
      color: white;
      border: none;
      padding: 12px 30px;
      border-radius: 8px;
      font-size: 16px;
      cursor: pointer;
      transition: all 0.3s ease;
    }
    
    .level-up-btn:hover {
      background: #7c3aed;
      transform: scale(1.05);
    }
    
    /* 关卡3特定样式 */
    .coffee-shop {
      background: linear-gradient(135deg, #fef3c7 0%, #fcd34d 100%);
      border-radius: 15px;
      padding: 25px;
    }
    
    .coffee-shop h3 {
      color: #92400e;
      margin-bottom: 15px;
      text-align: center;
    }
    
    .order-details {
      background: white;
      border-radius: 10px;
      padding: 15px;
      margin-bottom: 20px;
    }
    
    .total-price {
      font-size: 1.5rem;
      font-weight: bold;
      color: #b45309;
      text-align: center;
      margin-bottom: 20px;
    }
    
    .add-btn {
      background: #d97706;
      color: white;
      border: none;
      padding: 12px 30px;
      border-radius: 8px;
      font-size: 16px;
      cursor: pointer;
      transition: all 0.3s ease;
      display: block;
      margin: 0 auto;
    }
    
    .add-btn:hover {
      background: #b45309;
      transform: scale(1.05);
    }
    
    /* 关卡4特定样式 */
    .watch-game {
      background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
      border-radius: 15px;
      padding: 25px;
    }
    
    .coordinates {
      background: white;
      border-radius: 10px;
      padding: 15px;
      margin-bottom: 20px;
      text-align: center;
    }
    
    .coordinates p {
      font-size: 1.2rem;
      font-weight: bold;
      color: #1e40af;
    }
    
    .move-buttons {
      display: flex;
      justify-content: center;
      gap: 10px;
      margin-bottom: 20px;
    }
    
    .move-btn {
      background: #3b82f6;
      color: white;
      border: none;
      padding: 10px 20px;
      border-radius: 8px;
      font-size: 16px;
      cursor: pointer;
      transition: all 0.3s ease;
    }
    
    .move-btn:hover {
      background: #2563eb;
      transform: scale(1.05);
    }
    
    /* 关卡5特定样式 */
    .ts-showcase {
      background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);
      border-radius: 15px;
      padding: 25px;
    }
    
    .code-block {
      background: #1e1e1e;
      color: #d4d4d4;
      border-radius: 10px;
      padding: 15px;
      font-family: 'Courier New', monospace;
      overflow-x: auto;
      margin-bottom: 20px;
    }
    
    .code-keyword {
      color: #569cd6;
    }
    
    .code-type {
      color: #4ec9b0;
    }
    
    .code-number {
      color: #b5cea8;
    }
    
    /* 关卡6特定样式 */
    .quiz-game {
      background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);
      border-radius: 15px;
      padding: 25px;
    }
    
    .quiz-question {
      background: white;
      border-radius: 10px;
      padding: 20px;
      margin-bottom: 20px;
    }
    
    .quiz-question h4 {
      color: #065f46;
      margin-bottom: 15px;
    }
    
    .quiz-answer {
      background: #f0fdf4;
      border-left: 4px solid #16a34a;
      padding: 15px;
      border-radius: 5px;
      font-style: italic;
    }
    
    /* 关卡7特定样式 */
    .challenge-area {
      background: linear-gradient(135deg, #fbcfe8 0%, #f9a8d4 100%);
      border-radius: 15px;
      padding: 25px;
    }
    
    .challenges {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 20px;
    }
    
    .challenge-card {
      background: white;
      border-radius: 10px;
      padding: 20px;
      box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
    }
    
    .challenge-card h4 {
      color: #be185d;
      margin-bottom: 10px;
    }
    
    .progress-bar {
      height: 10px;
      background: #e5e7eb;
      border-radius: 5px;
      margin-top: 20px;
      overflow: hidden;
    }
    
    .progress-fill {
      height: 100%;
      background: linear-gradient(90deg, #667eea, #764ba2);
      transition: width 0.5s ease;
    }
    
    .game-footer {
      text-align: center;
      margin-top: 30px;
      padding-top: 20px;
      border-top: 2px solid #667eea;
      color: #666;
    }
    
    .success-message {
      background: #dcfce7;
      color: #166534;
      padding: 15px;
      border-radius: 10px;
      margin-bottom: 20px;
      display: flex;
      align-items: center;
      font-weight: bold;
    }
    
    .success-message .icon {
      margin-right: 10px;
      font-size: 1.5rem;
    }
    
    @media (max-width: 768px) {
      .game-container {
        padding: 20px;
      }
      
      .game-header h1 {
        font-size: 2rem;
      }
      
      .challenges {
        grid-template-columns: 1fr;
      }
    }
  </style>
</head>
<body>
  <div id="app">
    <div class="game-container">
      <div class="game-header">
        <h1><span>🎮</span> Vue3 响应式学习游戏</h1>
        <p>完成所有7个关卡，成为Vue3响应式小法师！</p>
        <div class="progress-bar">
          <div class="progress-fill" :style="{ width: `${(currentLevel / totalLevels) * 100}%` }"></div>
        </div>
      </div>
      
      <div class="level-selector">
        <button 
          v-for="level in levels" 
          :key="level.id"
          class="level-btn" 
          :class="{ 
            active: currentLevel === level.id, 
            completed: completedLevels.includes(level.id),
            locked: !isLevelUnlocked(level.id)
          }"
          @click="goToLevel(level.id)"
          :disabled="!isLevelUnlocked(level.id)"
        >
          {{ level.id }}
          <span v-if="completedLevels.includes(level.id)" class="star">⭐</span>
        </button>
      </div>
      
      <div class="game-content">
        <div v-if="successMessage" class="success-message">
          <span class="icon">🎉</span>
          {{ successMessage }}
        </div>
        
        <!-- 关卡0：介绍 -->
        <div v-if="currentLevel === 0">
          <div class="level-title">
            <span class="emoji">🌟</span>
            关卡 0｜开局一句话
          </div>
          <div class="learning-points">
            <h3>学习要点</h3>
            <p style="text-align: center; font-size: 1.2rem; color: #667eea; font-weight: bold;">
              Vue3 的响应式 = "数据变，DOM 自动变"<br>
              而你只用关心数据本身，Vue 帮你当"渲染打工人"。
            </p>
          </div>
          <div style="text-align: center; margin-top: 40px;">
            <button class="level-up-btn" @click="goToLevel(1)">开始闯关！🚀</button>
          </div>
        </div>
        
        <!-- 关卡1：ref -->
        <div v-if="currentLevel === 1">
          <div class="level-title">
            <span class="emoji">🌟</span>
            关卡 1｜ref：让"原始值"变成"响应式小精灵"
          </div>
          
          <div class="learning-points">
            <h3>学习点</h3>
            <ul>
              <li>ref 包裹基本类型（string / number / boolean）</li>
              <li>在模板或 computed 里直接裸用，在脚本里要 .value</li>
            </ul>
          </div>
          
          <div class="analogy">
            <h3>趣味比喻</h3>
            <p>把 ref 想象成"魔法存钱罐"：外面看是一个整体，里面实际藏着金币（.value）。你摇一摇（修改.value），页面就会发光（更新）。</p>
            <div class="decoration">💰</div>
          </div>
          
          <div class="demo-area">
            <h3>🎯 互动演示：勇者血量</h3>
            <div class="hero-game">
              <div class="hero-hp">勇者血量：{{ hp }}❤️</div>
              <button class="hero-btn" @click="attack" :disabled="attacking">
                {{ attacking ? '攻击中...⚔️' : '发起攻击⚔️' }}
              </button>
            </div>
          </div>
          
          <div style="text-align: center; margin-top: 30px;">
            <button class="level-up-btn" @click="completeLevel(1)">完成关卡！✅</button>
          </div>
        </div>
        
        <!-- 关卡2：reactive -->
        <div v-if="currentLevel === 2">
          <div class="level-title">
            <span class="emoji">🌟</span>
            关卡 2｜reactive：让"对象"一次响应到底
          </div>
          
          <div class="learning-points">
            <h3>学习点</h3>
            <ul>
              <li>reactive 只能包裹对象/数组；内部所有属性都会被递归代理</li>
              <li>解构 reactive 会"丢响应"，要用 toRefs 或保持整体引用</li>
            </ul>
          </div>
          
          <div class="analogy">
            <h3>趣味比喻</h3>
            <p>reactive 像"响应式大别墅"：门牌号是整栋别墅，拆走一块砖（解构）就失去魔法。</p>
            <div class="decoration">🏠</div>
          </div>
          
          <div class="demo-area">
            <h3>🎯 互动演示：英雄升级</h3>
            <div class="hero-card">
              <h3>{{ hero.name }}</h3>
              <div class="hero-level">Lv.{{ hero.level }}</div>
              <div class="hero-skills">
                技能：{{ hero.skills.join('、') }}
              </div>
              <button class="level-up-btn" @click="levelUp">打怪升级⚔️</button>
            </div>
          </div>
          
          <div style="text-align: center; margin-top: 30px;">
            <button class="level-up-btn" @click="completeLevel(2)">完成关卡！✅</button>
          </div>
        </div>
        
        <!-- 关卡3：computed -->
        <div v-if="currentLevel === 3">
          <div class="level-title">
            <span class="emoji">🌟</span>
            关卡 3｜computed：声明式"衍生数据"
          </div>
          
          <div class="learning-points">
            <h3>学习点</h3>
            <ul>
              <li>根据已有响应式数据自动计算出值，带缓存</li>
              <li>不要修改 computed 本身，它是"只读精灵"</li>
            </ul>
          </div>
          
          <div class="analogy">
            <h3>趣味比喻</h3>
            <p>computed 像"自动奶茶机"：你放原料（ref/reactive），它自动出奶茶（计算结果），原料不变奶茶不重新做。</p>
            <div class="decoration">🧋</div>
          </div>
          
          <div class="demo-area">
            <h3>🎯 互动演示：奶茶店收银</h3>
            <div class="coffee-shop">
              <h3>☕ 奶茶订单</h3>
              <div class="order-details">
                <p>单价：{{ price }} 元 × 数量：{{ quantity }} 杯 × 折扣：{{ discount }}</p>
              </div>
              <div class="total-price">应付：{{ total.toFixed(2) }} 元</div>
              <button class="add-btn" @click="addCoffee">再来一杯➕</button>
            </div>
          </div>
          
          <div style="text-align: center; margin-top: 30px;">
            <button class="level-up-btn" @click="completeLevel(3)">完成关卡！✅</button>
          </div>
        </div>
        
        <!-- 关卡4：watch & watchEffect -->
        <div v-if="currentLevel === 4">
          <div class="level-title">
            <span class="emoji">🌟</span>
            关卡 4｜watch & watchEffect：侧效应"侦察兵"
          </div>
          
          <div class="learning-points">
            <h3>学习点</h3>
            <ul>
              <li>watch：精确监听指定数据源，可拿到新旧值</li>
              <li>watchEffect：立即运行一次，并收集依赖，适合"自动触发"场景</li>
            </ul>
          </div>
          
          <div class="analogy">
            <h3>趣味比喻</h3>
            <p>watch 是"定点监控摄像头"；watchEffect 是"AI 巡检无人机"，飞一圈看到啥就记录啥。</p>
            <div class="decoration">🛸</div>
          </div>
          
          <div class="demo-area">
            <h3>🎯 互动演示：角色移动</h3>
            <div class="watch-game">
              <h3>🕹️ 移动角色</h3>
              <div class="coordinates">
                <p>角色坐标：({{ x }}, {{ y }})</p>
              </div>
              <div class="move-buttons">
                <button class="move-btn" @click="moveLeft">⬅️</button>
                <button class="move-btn" @click="moveUp">⬆️</button>
                <button class="move-btn" @click="moveDown">⬇️</button>
                <button class="move-btn" @click="moveRight">➡️</button>
              </div>
              <div style="text-align: center; margin-top: 20px; font-size: 0.9rem; color: #666;">
                <p>打开浏览器控制台，查看 watchEffect 的自动监听效果！</p>
              </div>
            </div>
          </div>
          
          <div style="text-align: center; margin-top: 30px;">
            <button class="level-up-btn" @click="completeLevel(4)">完成关卡！✅</button>
          </div>
        </div>
        
        <!-- 关卡5：TypeScript -->
        <div v-if="currentLevel === 5">
          <div class="level-title">
            <span class="emoji">🌟</span>
            关卡 5｜script setup + 类型推断：TS 丝滑连招
          </div>
          
          <div class="learning-points">
            <h3>技巧清单</h3>
            <ul>
              <li>顶层变量自动暴露给模板，无需 return</li>
              <li>用 interface / type 描述 props & emit，让 Vetur/Volar 给你智能提示</li>
              <li>给 ref/reactive 加泛型，写错会飘红，比 console 报错更早</li>
            </ul>
          </div>
          
          <div class="demo-area">
            <h3>🎯 TypeScript 代码示例</h3>
            <div class="ts-showcase">
              <div class="code-block">
                <span class="code-keyword">const</span> score = ref<<span class="code-type">number</span>>(<span class="code-number">98</span>); <span style="color: #6a9955;">// 正确的类型注解</span><br>
                <span class="code-keyword">const</span> name = ref<<span class="code-type">string</span>>("Vue 法师"); <span style="color: #6a9955;">// 正确的类型注解</span><br>
                <br>
                <span style="color: #ce9178;">interface</span> <span class="code-type">Hero</span> {<br>
                &nbsp;&nbsp;name: <span class="code-type">string</span>;<br>
                &nbsp;&nbsp;level: <span class="code-type">number</span>;<br>
                &nbsp;&nbsp;skills: <span class="code-type">string</span>[];<br>
                }<br>
                <br>
                <span class="code-keyword">const</span> hero = reactive<<span class="code-type">Hero</span>>({
                &nbsp;&nbsp;name: "Vue 法师",
                &nbsp;&nbsp;level: <span class="code-number">1</span>,
                &nbsp;&nbsp;skills: ["火球术"]
                });
              </div>
              
              <div style="text-align: center; margin-top: 20px; font-size: 0.9rem; color: #666;">
                <p>💡 在支持 TypeScript 的编辑器中，错误的类型注解会立即显示红色波浪线！</p>
              </div>
            </div>
          </div>
          
          <div style="text-align: center; margin-top: 30px;">
            <button class="level-up-btn" @click="completeLevel(5)">完成关卡！✅</button>
          </div>
        </div>
        
        <!-- 关卡6：常见问题 -->
        <div v-if="currentLevel === 6">
          <div class="level-title">
            <span class="emoji">🌟</span>
            关卡 6｜常见掉坑题（趣味抢答）
          </div>
          
          <div class="demo-area">
            <h3>🎯 挑战你的知识！</h3>
            <div class="quiz-game">
              <div class="quiz-question">
                <h4>Q1: 为什么 const { count } = ref(0) 丢失响应？</h4>
                <div class="quiz-answer">
                  A: 解构的是基本值，脱离 ref 包裹；正确用 const { count } = toRefs(reactive({ count: 0 }))。
                </div>
              </div>
              
              <div class="quiz-question">
                <h4>Q2: 直接给 reactive 数组 push 新对象，会响应吗？</h4>
                <div class="quiz-answer">
                  A: 会！reactive 数组方法被代理，放心 push。
                </div>
              </div>
              
              <div class="quiz-question">
                <h4>Q3: 在定时器里修改 ref，视图会更新吗？</h4>
                <div class="quiz-answer">
                  A: 会！Vue3 代理不受"异步限制"困扰，无需 $nextTick。
                </div>
              </div>
            </div>
          </div>
          
          <div style="text-align: center; margin-top: 30px;">
            <button class="level-up-btn" @click="completeLevel(6)">完成关卡！✅</button>
          </div>
        </div>
        
        <!-- 关卡7：小作业 -->
        <div v-if="currentLevel === 7">
          <div class="level-title">
            <span class="emoji">🌟</span>
            关卡 7｜最终挑战：综合应用
          </div>
          
          <div class="demo-area">
            <h3>🎯 实战挑战</h3>
            <div class="challenge-area">
              <p style="text-align: center; margin-bottom: 20px; font-weight: bold; color: #be185d;">
                恭喜你！你已经完成了所有基础关卡。以下是你可以尝试的实战项目：
              </p>
              
              <div class="challenges">
                <div class="challenge-card">
                  <h4>🌡️ 温度转换器</h4>
                  <p>用 ref + computed 做"摄氏 ↔ 华氏"实时转换器。</p>
                </div>
                
                <div class="challenge-card">
                  <h4>✅ 待办列表</h4>
                  <p>用 reactive + watch 做"待办列表"，剩余未完成数自动统计。</p>
                </div>
                
                <div class="challenge-card">
                  <h4>🖱️ 鼠标追踪</h4>
                  <p>用 watchEffect 监听鼠标位置，在页面实时显示坐标。</p>
                </div>
              </div>
              
              <div style="text-align: center; margin-top: 30px; font-weight: bold; color: #be185d;">
                <p>🌟 恭喜你成为 Vue3 响应式小法师！ 🌟</p>
              </div>
            </div>
          </div>
          
          <div style="text-align: center; margin-top: 30px;">
            <button class="level-up-btn" @click="completeLevel(7)">获得终极成就！🏆</button>
          </div>
        </div>
      </div>
      
      <div class="game-footer">
        <p>Vue3 响应式学习游戏 © 2023 | 按顺序完成关卡，解锁全部成就！</p>
      </div>
    </div>
  </div>

  <script>
    const { createApp, ref, reactive, computed, watchEffect } = Vue
    
    createApp({
      setup() {
        // 游戏状态管理
        const currentLevel = ref(0)
        const totalLevels = ref(7)
        const completedLevels = ref([])
        const successMessage = ref('')
        
        // 关卡数据
        const levels = [
          { id: 0, name: '开局一句话' },
          { id: 1, name: 'ref：响应式小精灵' },
          { id: 2, name: 'reactive：响应式大别墅' },
          { id: 3, name: 'computed：自动奶茶机' },
          { id: 4, name: 'watch & watchEffect：侦察兵' },
          { id: 5, name: 'TypeScript 类型推断' },
          { id: 6, name: '常见掉坑题' },
          { id: 7, name: '综合应用挑战' }
        ]
        
        // 检查关卡是否解锁 - 修改为所有关卡都可直接访问
        const isLevelUnlocked = (levelId) => {
          return true // 所有关卡都可直接访问，方便测试
        }
        
        // 切换关卡
        const goToLevel = (levelId) => {
          if (isLevelUnlocked(levelId)) {
            currentLevel.value = levelId
            successMessage.value = ''
          }
        }
        
        // 完成关卡
        const completeLevel = (levelId) => {
          if (!completedLevels.value.includes(levelId)) {
            completedLevels.value.push(levelId)
          }
          
          successMessage.value = `恭喜完成关卡 ${levelId}！🎉`
          
          // 如果还有下一关，自动解锁
          if (levelId < totalLevels.value) {
            setTimeout(() => {
              goToLevel(levelId + 1)
            }, 2000)
          } else {
            // 完成所有关卡
            setTimeout(() => {
              successMessage.value = '恭喜你完成所有关卡，成为Vue3响应式小法师！🎊'
            }, 2000)
          }
        }
        
        // ===== 关卡1：ref示例 =====
        const hp = ref(100)
        const attacking = ref(false)
        
        const attack = () => {
          if (!attacking.value) {
            attacking.value = true
            setTimeout(() => {
              hp.value -= 20
              attacking.value = false
              
              if (hp.value <= 0) {
                hp.value = 100 // 重置血量
                alert('勇者重新充满了力量！')
              }
            }, 500)
          }
        }
        
        // ===== 关卡2：reactive示例 =====
        const hero = reactive({
          name: 'Vue 法师',
          level: 1,
          skills: ['火球术']
        })
        
        const levelUp = () => {
          hero.level++
          
          if (hero.level === 3) {
            hero.skills.push('冰冻术')
            alert('恭喜学会新技能：冰冻术！🧊')
          } else if (hero.level === 5) {
            hero.skills.push('雷电术')
            alert('恭喜学会新技能：雷电术！⚡')
          }
        }
        
        // ===== 关卡3：computed示例 =====
        const price = ref(25)
        const quantity = ref(1)
        const discount = ref(0.9)
        
        const total = computed(() => {
          return price.value * quantity.value * discount.value
        })
        
        const addCoffee = () => {
          quantity.value++
          // 买3杯以上打8折
          if (quantity.value >= 3) {
            discount.value = 0.8
          }
        }
        
        // ===== 关卡4：watchEffect示例 =====
        const x = ref(0)
        const y = ref(0)
        
        // 使用watchEffect自动监听坐标变化
        watchEffect(() => {
          console.log(`角色坐标更新：(${x.value}, ${y.value})`)
        })
        
        const moveLeft = () => x.value -= 10
        const moveRight = () => x.value += 10
        const moveUp = () => y.value -= 10
        const moveDown = () => y.value += 10
        
        return {
          // 游戏状态
          currentLevel,
          totalLevels,
          completedLevels,
          levels,
          successMessage,
          
          // 游戏方法
          isLevelUnlocked,
          goToLevel,
          completeLevel,
          
          // 关卡1
          hp,
          attacking,
          attack,
          
          // 关卡2
          hero,
          levelUp,
          
          // 关卡3
          price,
          quantity,
          discount,
          total,
          addCoffee,
          
          // 关卡4
          x,
          y,
          moveLeft,
          moveRight,
          moveUp,
          moveDown
        }
      }
    }).mount('#app')
  </script>
</body>
</html>